package main
import (
	"fmt"
)

//  15. 指针 指针是一种存储变量内存地址（Memory Address）的变量。
func main(){

    b := 255
    var a * int = &b    //& 操作符用于获取变量的地址 *a可以拿到该值
    fmt.Printf("Type of a is %T\n", a)
    fmt.Println("addres of a is", a)
    fmt.Println("addres of *a is", *a)

    // 指针的零值（Zero Value）
    aaa := 255
    var bbb *int
    if bbb == nil {
        fmt.Println("\nb is", bbb)
        bbb = &aaa
        fmt.Println("b after initialization is", bbb)
    }

    // 同一个指针 修改值的时候 后面用到内存地址的值都是一样的
    fmt.Println("\nbbb", *bbb)
    *bbb++
    fmt.Println("修改后b", *bbb)
    fmt.Println("修改后a", aaa)

    // 向函数传递指针参数
    fmt.Println("传指针前", aaa)
    change(bbb)
    fmt.Println("传指针后", aaa)

    // 不要向函数传递数组的指针，而应该使用切片
    arr1 := [3]int{89, 90, 26}
    modify(&arr1)
    fmt.Println("\n",arr1)
    // 切片 这种方式向函数传递一个数组指针参数，并在函数内修改数组。尽管它是有效的，但却不是 Go 语言惯用的实现方式。我们最好使用切片来处理。
    modify1(arr1[:])
    fmt.Println("\n 切片",arr1) //所以别再传递数组指针了，而是使用切片吧。上面的代码更加简洁，也更符合 Go 语言的习惯。
    

    // Go 不支持指针运算 报错
    // b1 := [...]int{12, 34, 56}
    // p := &b1
    // *p++ //invalid operation: p++ (non-numeric type *[3]int)
    // fmt.Println("\n Go 不支持指针运算",b1)



}

// 向函数传递指针参数
func change(val *int) {
    *val = 55
}
// 不要向函数传递数组的指针，而应该使用切片
func modify(arr *[3]int) {
    // (*arr)[0] =  9999  // 简写
    arr[0] =  9999
}
// 切片
func modify1(sls []int) {
    sls[0] = 999
}